package main

import (
	"context"
	"fmt"
	"sync"
	"time"
)

var wait = sync.WaitGroup{}

func main() {
	wait.Add(1)
	t1 := time.Now()
	ctx, cancel := context.WithCancel(context.Background())
	go func() {
		ip, err := GetIp(ctx)
		if err != nil {
			panic(err)
		}
		fmt.Println(ip)
	}()

	// 模拟超时, 2s后取消
	go func() {
		time.Sleep(time.Second * 2)
		// time.Sleep(time.Second * 2)
		fmt.Println("cancel is called")
		cancel()
	}()

	wait.Wait()
	fmt.Println("main end", time.Since(t1))
}

func GetIp(ctx context.Context) (ip string, err error) {
	go func() {
		select {
		case <-ctx.Done():
			if ctx.Err() == context.Canceled {
				fmt.Println("GetIp is cancelled", ctx.Err())
				wait.Done()
				return
			}
		}
	}()
	time.Sleep(time.Second * 4)
	ip = "10.32.12.32"
	wait.Done()
	return ip, nil
}
